package com.yingsheng.bi.hks.service.user;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import com.yingsheng.bi.hks.basic.PUser;
import com.yingsheng.bi.hks.basic.consts.MsgDict;
import com.yingsheng.bi.hks.basic.exception.ServiceRuntimeException;
import com.yingsheng.bi.hks.basic.utils.Subject;
import com.yingsheng.bi.hks.dto.user.UserLoginRes;
import com.yingsheng.bi.hks.dto.user.WxAuthLoginReq;
import com.yingsheng.bi.hks.mapping.LoginMappings;
import com.yingsheng.bi.hks.repository.dao.po.Role;
import com.yingsheng.bi.hks.repository.dao.po.UserBinds;
import com.yingsheng.bi.hks.repository.dao.po.Users;
import com.yingsheng.bi.hks.repository.dao.service.UserBindsDaoService;
import com.yingsheng.bi.hks.repository.dao.service.UserLoginDaoService;
import com.yingsheng.bi.hks.repository.dao.service.UserRoleDaoService;
import com.yingsheng.bi.hks.repository.dao.service.UsersDaoService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class LoginBiService {

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private UsersDaoService usersDaoService;

    @Autowired
    private UserBindsDaoService userBindsDaoService;

    @Autowired
    private UserLoginDaoService userLoginDaoService;

    @Autowired
    private UserRoleDaoService userRoleDaoService;

    public UserLoginRes process(WxAuthLoginReq req) {
        // 1.获取微信授权手机号
        WxMaPhoneNumberInfo wxMaPhoneNumberInfo;
        try {
            wxMaPhoneNumberInfo = wxMaService.getUserService().getPhoneNoInfo(req.getPhoneCode());
        } catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            throw new ServiceRuntimeException(MsgDict.WX_MINIAPP_PHONE_ERROR);
        }
        // 2.获取微信授权登录凭证
        WxMaJscode2SessionResult session;
        try {
            session = wxMaService.getUserService().getSessionInfo(req.getLoginCode());
        } catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            throw new ServiceRuntimeException(MsgDict.WX_MAXIAPP_LOGIN_ERROR);
        } finally {
            WxMaConfigHolder.remove();//清理ThreadLocal
        }
        log.info(session.getSessionKey());
        log.info(session.getOpenid());
        String mobile = wxMaPhoneNumberInfo.getPhoneNumber();
        String openId = session.getOpenid();
        String sessionId = session.getSessionKey();
//        String mobile = "15757871122";
//        String openId = "123456789";
//        String sessionId = "789456123";
        String channel = req.getChannel();
        /**
         *  判断是否首次授权进行区分处理：
         *  第一次授权相当于注册，通过手机号注册用户并与微信绑定
         *  第二次授权相当于登录，如果手机号变更了需要更新手机号
         */
        Users users = null;
        Role role = null;
        UserBinds userBinds = userBindsDaoService.query(channel, openId);
        if (userBinds == null) {
            users = usersDaoService.registerUser(channel, mobile);
            userBindsDaoService.insert(channel, openId, users.getId());
            userLoginDaoService.insert(users.getId(), sessionId, req.getLoginDeviceName());
            role = userRoleDaoService.createUserRole(users.getId());
        } else {
            users = usersDaoService.selectByUserId(userBinds.getUserId());
            if (!mobile.equals(users.getMobile())) {
                usersDaoService.updateMobileByUserId(users.getId(), mobile);
            }
            userLoginDaoService.update(users.getId(), sessionId, req.getLoginDeviceName());
            role = userRoleDaoService.queryRoleByUserId(users.getId());
        }
        /**
         * 设置会话信息
         */
        PUser pUser = LoginMappings.INSTANCE.userAndRolePo2PUser(users, role);
        pUser.setOpenId(openId);
        Subject.set(pUser);
        UserLoginRes res = LoginMappings.INSTANCE.userPo2LoginRes(pUser);
        res.setAvatar(users.getAvatar());
        res.setRecommendationId(users.getRecommendationId());
        return res;
    }

}
